package com.bite.ojsystem.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.bite.ojcommoncore.constants.HttpConstants;
import com.bite.ojcommoncore.constants.RateConstants;
import com.bite.ojcommoncore.constants.CacheConstant;
import com.bite.ojcommoncore.domain.entity.LoginSysUser;
import com.bite.ojcommoncore.domain.result.R;
import com.bite.ojcommoncore.enums.ResultCode;
import com.bite.ojcommoncore.utils.ThreadLocalUtils;
import com.bite.ojcommonredis.service.RedisService;
import com.bite.ojcommonsecurity.exception.UnAuthorizationException;
import com.bite.ojcommonsecurity.exception.UserNotExistException;
import com.bite.ojcommonsecurity.service.TokenService;
import com.bite.ojcommonsecurity.utils.SecurityUtils;
import com.bite.ojsystem.domain.SysUser;
import com.bite.ojsystem.domain.dto.LoginSysUserDto;
import com.bite.ojsystem.domain.vo.LoginUserVO;
import com.bite.ojsystem.domain.vo.SysUserVO;
import com.bite.ojsystem.mapper.SysUserMapper;
import com.bite.ojsystem.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private RedisService redisService;

    @Value("jwt.secret")
    private String secret;



    // 实现用户登录方法
    @Override
    public R<String> login(LoginSysUserDto loginSysUserDto) {
        // ①根据账号查询用户信息
        LambdaQueryWrapper<SysUser> queryWrapper = new LambdaQueryWrapper<>();
        SysUser sysUser = sysUserMapper.selectOne(queryWrapper
                .select(SysUser::getPassword, SysUser::getUserId, SysUser::getNickName)
                .eq(SysUser::getUserAccount, loginSysUserDto.getUserAccount()));
        // 账号不存在，返回账户密码不存在
        if (sysUser == null) {
            return R.fail(ResultCode.FAILED_USER_NOT_EXISTS.getCode(), ResultCode.FAILED_USER_NOT_EXISTS.getMsg());
        }
        // 账号存在，判断密码是否相等
        if (!SecurityUtils.matchesPassword(loginSysUserDto.getPassword(), sysUser.getPassword())) {
            return R.fail(ResultCode.FAILED_LOGIN.getCode(), ResultCode.FAILED_LOGIN.getMsg());
        }

        // ②生成token  token 保存用户id 用户账号 用户身份 --- 管理员 普通用户
        String token = TokenService.createToken(sysUser.getUserId(), RateConstants.ADMIN, secret);

        // ③将用户敏感信息保存在redis中
        String tokenKey = CacheConstant.LOGIN_USER_CACHE_KEY + sysUser.getUserId();
        LoginSysUser loginSysUser = LoginSysUser.builder()
                .identity(RateConstants.ADMIN)
                .nickName(sysUser.getNickName())
                .userAccount(loginSysUserDto.getUserAccount())
                .build();
        redisService.setCacheObject(tokenKey, loginSysUser,
                CacheConstant.LOGIN_USER_TTL, TimeUnit.MINUTES);

        //TODO  ④保存用户身份信息在threadlocal中
        //  ThreadLocalUtils.setUserId(sysUser.getUserId());

        // ⑤返回token给前端
        return  R.ok(null,token);

    }


    public boolean save(LoginSysUserDto loginSysUserDto) {
        // 保存用户 -- 对用户数据进行初始化
        SysUser sysUser = new SysUser();
        sysUser.setUserAccount(loginSysUserDto.getUserAccount());
        sysUser.setPassword(SecurityUtils.encryptPassword(loginSysUserDto.getPassword()));
        sysUser.setNickName(loginSysUserDto.getUserAccount());
        int row = sysUserMapper.insert(sysUser);
        if (row < 1) {
            log.error("用户保存失败 {}" , sysUser.getUserAccount());
            return false;
        }
        return true;
    }

    @Override
    public SysUserVO getCurrentUser(String token) {
        // ①对token进行处理 判断前面是否有Bearer
        if (StrUtil.isNotEmpty(token) && StrUtil.startWith(token, HttpConstants.PREFIX)) {
            token = token.replaceFirst(HttpConstants.PREFIX , StrUtil.EMPTY);
        }

        // ②解析token，获取tokenkey
        String tokenKey = TokenService.getTokenKey(token, secret);

        // ③根据tokenkey从redis获取登录用户信息
        LoginSysUser loginSysUser = redisService.getCacheObject(tokenKey, LoginSysUser.class);

        // ④将用户信息赋值给VO返回给前端
        SysUserVO sysUserVO = SysUserVO.builder()
                .nickName(loginSysUser.getNickName())
                .userAccount(loginSysUser.getUserAccount()).build();

        return sysUserVO;
    }
//    @Override
//    public SysUserVO getCurrentUser(String token) {
//
//        Long userId = ThreadLocalUtils.getUserId();
//        if (userId == null) {
//            log.error("用户未登录");
//            throw new UnAuthorizationException("用户未登录");
//        }
//        SysUser sysUser = sysUserMapper.selectById(userId);
//        if (sysUser == null) {
//            throw new UserNotExistException("用户不存在");
//        }
//        SysUserVO sysUserVO = new SysUserVO();
//        sysUserVO.setUserAccount(sysUser.getUserAccount());
//        sysUserVO.setNickName(sysUser.getNickName());
//        return sysUserVO;
//    }
}





